<template>
  <div id="app">
    <div class="container">
      <el-card>
        <div slot="header">
          <h2>可转债</h2>
        </div>
        <filter-input style="margin: 1rem 0;" :data="source_data" :mappings="source_mappings">
            <el-table slot="data-table" slot-scope="props" :data="props.data" stripe border size="small">
            <el-table-column prop="code" label="代码"></el-table-column>
            <el-table-column prop="name" label="名称"></el-table-column>
            <el-table-column
              prop="rate"
              label="评级"
              sortable
              sort-by="rate_rank"
              :sort-orders="sort_order_descending"
            ></el-table-column>
            <el-table-column prop="price" label="价格" sortable :sort-orders="sort_order_descending"></el-table-column>
            <el-table-column
              prop="gain_rate"
              label="到期收益率(税后)"
              :width="150"
              sortable
              :sort-method="gainRateSortFunc"
              :sort-orders="sort_order_descending"
            ></el-table-column>
            <el-table-column
              prop="redeem"
              label="强赎天计数"
              sortable
              sort-by="redeem_rank"
              :sort-orders="sort_order_descending"
            ></el-table-column>
            <el-table-column
              prop="extime"
              label="到期时间"
              sortable
              :sort-orders="sort_order_descending"
            ></el-table-column>
            <el-table-column label="详情">
              <template slot-scope="scope">
                <el-link
                  type="primary"
                  size="mini"
                  target="_blank"
                  :href="'https://www.jisilu.cn/data/convert_bond_detail/'+scope.row.code"
                >详情</el-link>
              </template>
            </el-table-column>
          </el-table>
        </filter-input>
      </el-card>
    </div>
  </div>
</template>

<script>
import "bootstrap/dist/css/bootstrap.css";
import FilterInput from "@/components/FilterInput.vue";

export default {
  name: "App",
  components: {
    FilterInput,
  },
  data() {
    return {
      source_data: [],
      sort_order_descending: ["descending", "ascending", null],
      default_sort: {
        prop: "rate",
        order: "descending",
      },
      source_mappings: [
        {
          name: "评级",
          field: "rate_rank",
          type: "select",
          options: {
            selections: {
              AAA: this.rateTransform("AAA"),
              AA: this.rateTransform("AA"),
              A: this.rateTransform("A"),
            },
          },
        },
        {
          name: "价格",
          field: "price",
          type: "decimal",
        },
        {
          name: "到期收益率 %",
          field: "gain_rate",
          compareFunc(a, op, b, defaultFunc){
            let left, right
            left = parseFloat(a)
            right = parseFloat(b)
            return defaultFunc(left, op, right)
          },
          type: "decimal",
        },
        {
          name: "强赎天计数",
          field: "redeem_rank",
          operators: ["满足", "不满足"],
          compareFunc(a, op, b, defaultFunc) {
            let mapop = {
              "满足": "=",
              "不满足": "<",
            }
            let mapb = {
              "强赎条件": 1,
              "已公告强赎": 100,
              "公告不强赎": 50,
            }
            return defaultFunc(a, mapop[op], mapb[b])
          },
          type: "select",
          options: {
            selections: ["强赎条件", "已公告强赎", "公告不强赎"],
          },
        },
        {
          name: "到期时间",
          field: "extime",
          type: "date",
        },
      ],
    };
  },
  mounted() {
    this.fetchSource();
  },
  methods: {
    fetchSource() {
      let thes = this;
      fetch("/api")
        .then((res) => res.json())
        .then(function (jData) {
          thes.source_data = thes.transferData(jData);
        });
    },
    transferData(data) {
      let thes = this;
      let cbd = [];
      let rows = data.rows || [];
      for (let i = 0; i < rows.length; i++) {
        let row = rows[i];
        let cell = rows[i].cell;
        cbd.push({
          code: row.id,
          name: cell.bond_nm,
          rate: cell.issuer_rating_cd || cell.rating_cd,
          price: parseFloat(cell.full_price),
          gain_rate: cell.ytm_rt_tax,
          redeem:
            cell.redeem_flag === "X"
              ? cell.redeem_real_days + "/" + cell.redeem_total_days
              : cell.redeem_flag === "Y"
              ? "已公告强赎"
              : "公告不强赎",
          extime: cell.maturity_dt,
          link: "https://www.jisilu.cn/data/convert_bond_detail/" + row.id,
          rate_rank: thes.rateTransform(
            cell.issuer_rating_cd || cell.rating_cd
          ),
          redeem_rank: thes.redeemTransform(
            cell.redeem_flag,
            cell.redeem_real_days,
            cell.redeem_total_days
          ),
        });
      }
      return cbd;
    },
    rateTransform(a) {
      switch (a) {
        case "AAA":
          return 9;
        case "AAA-":
          return 8;
        case "AA+":
          return 7;
        case "AA":
          return 6;
        case "AA-":
          return 5;
        case "A+":
          return 4;
        case "A":
          return 3;
        case "A-":
          return 2;
        case "B+":
          return 1;
        default:
          return 0;
      }
    },
    redeemTransform(flag, days, total_days) {
      if (flag === "X") {
        // 强赎计数
        return days / total_days;
      } else if (flag === "Y") {
        // 已公告强赎
        return 100;
      } else {
        // 公告不强赎
        return 50;
      }
    },
    gainRateSortFunc(a, b) {
      // 到期收益率的排序函数
      a = a.gain_rate;
      b = b.gain_rate;
      return parseFloat(a) - parseFloat(b);
    },
  },
};
</script>

<style>
#app {
  font-family: Avenir, Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-align: center;
  color: #2c3e50;
  margin-top: 60px;
}
</style>
